<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>数字图像处理（DIP） | 啊粥啊周舟の部落阁</title><meta name="author" content="Zhouwy"><meta name="copyright" content="Zhouwy"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="数字图像处理（基于Python-Opencv）第一章 图像基础1.1 图像的基本概念（1）图像的颜色 色度学理论认为，任何颜色可由红、绿、蓝三种基本颜色混合得到。n图像可用红、绿、蓝三原色来表示。 f(x,y,z) &#x3D; \{fred(x,y,z),fgreen(x,y,z),fbule(x,y,z)\}（2）图像的表示 一般来说，图像是一个标准的矩形，有着宽度（width）和高度（height）。">
<meta property="og:type" content="article">
<meta property="og:title" content="数字图像处理（DIP）">
<meta property="og:url" content="https://gitee.com/zwyywz/zwyywz.git/2020/04/26/DigitalImageProcessing/index.html">
<meta property="og:site_name" content="啊粥啊周舟の部落阁">
<meta property="og:description" content="数字图像处理（基于Python-Opencv）第一章 图像基础1.1 图像的基本概念（1）图像的颜色 色度学理论认为，任何颜色可由红、绿、蓝三种基本颜色混合得到。n图像可用红、绿、蓝三原色来表示。 f(x,y,z) &#x3D; \{fred(x,y,z),fgreen(x,y,z),fbule(x,y,z)\}（2）图像的表示 一般来说，图像是一个标准的矩形，有着宽度（width）和高度（height）。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/DIP.png">
<meta property="article:published_time" content="2020-04-26T01:25:00.000Z">
<meta property="article:modified_time" content="2023-04-16T13:03:52.930Z">
<meta property="article:author" content="Zhouwy">
<meta property="article:tag" content="Python">
<meta property="article:tag" content="OpenCV">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/DIP.png"><link rel="shortcut icon" href="/zwyywz/img/favicon.png"><link rel="canonical" href="https://gitee.com/zwyywz/zwyywz.git/2020/04/26/DigitalImageProcessing/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/zwyywz/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/zwyywz/',
  algolia: undefined,
  localSearch: undefined,
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":300},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: true,
    post: true
  },
  runtime: '',
  dateSuffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: {"limitCount":50,"languages":{"author":"作者: Zhouwy","link":"链接: ","source":"来源: 啊粥啊周舟の部落阁","info":"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: true,
  }
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: '数字图像处理（DIP）',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2023-04-16 21:03:52'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
    win.getCSS = (url,id = false) => new Promise((resolve, reject) => {
      const link = document.createElement('link')
      link.rel = 'stylesheet'
      link.href = url
      if (id) link.id = id
      link.onerror = reject
      link.onload = link.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        link.onload = link.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(link)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><link rel="stylesheet" href="///at.alicdn.com/t/c/font_4018630_wl3l75i04vl.css"><meta name="generator" content="Hexo 6.3.0"></head><body><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/zwyywz/img/avatar.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/zwyywz/archives/"><div class="headline">文章</div><div class="length-num">17</div></a><a href="/zwyywz/tags/"><div class="headline">标签</div><div class="length-num">29</div></a><a href="/zwyywz/categories/"><div class="headline">分类</div><div class="length-num">5</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/zwyywz/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/zwyywz/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/zwyywz/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 分类</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/zwyywz/note/"><i class="fa-fw iconfont icon-xuexibiji"></i><span> 学习笔记</span></a></li><li><a class="site-page child" href="/zwyywz/opensource/"><i class="fa-fw iconfont icon-xiangmu"></i><span> 开源项目</span></a></li><li><a class="site-page child" href="/zwyywz/development/"><i class="fa-fw iconfont icon-peizhi-xitongpeizhi"></i><span> 环境配置</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 清单</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/zwyywz/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/zwyywz/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/zwyywz/link/"><i class="fa-fw fas fa-link"></i><span> 链接</span></a></div><div class="menus_item"><a class="site-page" href="/zwyywz/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://blog-1300216920.cos.ap-nanjing.myqcloud.com/DIP.png')"><nav id="nav"><span id="blog-info"><a href="/zwyywz/" title="啊粥啊周舟の部落阁"><span class="site-name">啊粥啊周舟の部落阁</span></a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page" href="/zwyywz/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/zwyywz/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/zwyywz/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 分类</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/zwyywz/note/"><i class="fa-fw iconfont icon-xuexibiji"></i><span> 学习笔记</span></a></li><li><a class="site-page child" href="/zwyywz/opensource/"><i class="fa-fw iconfont icon-xiangmu"></i><span> 开源项目</span></a></li><li><a class="site-page child" href="/zwyywz/development/"><i class="fa-fw iconfont icon-peizhi-xitongpeizhi"></i><span> 环境配置</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 清单</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/zwyywz/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/zwyywz/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/zwyywz/link/"><i class="fa-fw fas fa-link"></i><span> 链接</span></a></div><div class="menus_item"><a class="site-page" href="/zwyywz/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">数字图像处理（DIP）</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2020-04-26T01:25:00.000Z" title="发表于 2020-04-26 09:25:00">2020-04-26</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2023-04-16T13:03:52.930Z" title="更新于 2023-04-16 21:03:52">2023-04-16</time></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="数字图像处理（DIP）"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="数字图像处理（基于Python-Opencv）"><a href="#数字图像处理（基于Python-Opencv）" class="headerlink" title="数字图像处理（基于Python-Opencv）"></a>数字图像处理（基于Python-Opencv）</h1><h2 id="第一章-图像基础"><a href="#第一章-图像基础" class="headerlink" title="第一章 图像基础"></a>第一章 图像基础</h2><h3 id="1-1-图像的基本概念"><a href="#1-1-图像的基本概念" class="headerlink" title="1.1 图像的基本概念"></a>1.1 图像的基本概念</h3><p><strong>（1）图像的颜色</strong></p>
<p>色度学理论认为，任何颜色可由红、绿、蓝三种基本颜色混合得到。n图像可用红、绿、蓝三原色来表示。</p>
<script type="math/tex; mode=display">f(x,y,z) = \{fred(x,y,z),fgreen(x,y,z),fbule(x,y,z)\}</script><p><strong>（2）图像的表示</strong></p>
<p>一般来说，图像是一个标准的矩形，有着宽度（width）和高度（height）。而矩阵有着行（row）和列（column），矩阵的操作在数学和计算机中的处理都很常见且成熟，于是很自然的就把图像作为一个矩阵，把对图像的操作转换成对矩阵的操作。</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/矩阵.png" alt=""></p>
<p>$f_{mn}$代表该象素彩色或灰度值脚码代表象素的坐标位置:</p>
<p>使用opencv获取并修改像素值:读取一副图像，根据像素的行和列的坐标获取它的像素值，对于RGB图像而言，返回RGB的值，对于灰度图则返回灰度值。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> cv2</span><br><span class="line"><span class="keyword">import</span> numpy</span><br><span class="line">img = cv2.imread(<span class="string">&#x27;test.jpg&#x27;</span>)<span class="comment">#读入图片</span></span><br><span class="line"><span class="built_in">print</span>(img.size)<span class="comment">#输出图片的大小，返回图像的像素数目</span></span><br><span class="line"><span class="built_in">print</span>(img.shape)<span class="comment">#输出图片的形状，返回值是一个包含行数，列数，通道数的元组</span></span><br><span class="line"><span class="built_in">print</span>(img.dtype)<span class="comment">#返回图像的数据类型</span></span><br></pre></td></tr></table></figure>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/对应.png" alt=""></p>
<p><strong>图像空间分辨率</strong> :指图像数字化的空间精细程度。</p>
<p><strong>灰度级分辨率</strong>:即颜色深度，表示每一像素的颜色值所占的二进制位数。颜色深度越大则能表示的颜色数目越多。</p>
<h3 id="1-2-图像的存储格式"><a href="#1-2-图像的存储格式" class="headerlink" title="1.2 图像的存储格式"></a>1.2 图像的存储格式</h3><p>彩色图像是指每个像素的信息由R G B三原色构成的图像，其中R G B是由不同的灰度级来描述的:</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/image-20210429205546906.png" alt=""></p>
<p>(1) 颜色表红、绿、蓝分量值不全相等。<br>        (2) 像素值是图像颜色表的索引地址。</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/image-20210429205914771.png" alt=""></p>
<p>(1)每一像素由RGB三个分量组成。</p>
<p>(2)每个分量各占8位，取值范围为0~255，每个像素24位。</p>
<p>按照颜色深度分类,常用图像文件:</p>
<ul>
<li>黑白图像</li>
<li>8位索引图像</li>
<li>24位真彩色图像</li>
</ul>
<h2 id="第二章-基础操作"><a href="#第二章-基础操作" class="headerlink" title="第二章 基础操作"></a>第二章 基础操作</h2><h3 id="2-1-图像的算数运算"><a href="#2-1-图像的算数运算" class="headerlink" title="2.1 图像的算数运算"></a>2.1 图像的算数运算</h3><p><strong>1、图像加法</strong>：使用cv2.add()将两幅图像进行加法运算，也可以直接使用numpy，res=img1+img2。两幅图像的大小，类型必须一致，或者第二个图像可以是一个简单的标量值。openCV的加法是一种饱和操作，而numpy的加法是一种模操作。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">x=np.uint8([<span class="number">250</span>])</span><br><span class="line">y=np.uint8([<span class="number">10</span>])</span><br><span class="line"><span class="built_in">print</span>(cv2.add(x,y))<span class="comment">#250+10=260&gt;=255</span></span><br><span class="line"><span class="comment">#结果为[[255]]</span></span><br><span class="line"><span class="built_in">print</span> (x+y)<span class="comment">#250+10=260%255=4</span></span><br><span class="line"><span class="comment">#结果为[4]</span></span><br></pre></td></tr></table></figure>
<p><em>OpenCV的结果会更好，尽量使用OpenCV中的函数</em></p>
<p><strong>2、图像混合</strong>：这也是加法，不同的是两幅图像的权重不同，这会给人一种混合或者透明的感觉。图像混合的计算公式如下：</p>
<script type="math/tex; mode=display">
g(x) = (1−\alpha)f_0 (x)+\alpha f_1 (x)</script><p>通过修改$\alpha$的值（0—&gt;1）,可以实现很酷的混合。例：将两幅图像混合，第一幅权重为0.7.第二幅权重为0.3。函数cv2.addWeighed()可以按下面的公式对图片进行混合。$dst = \alpha·img1 + \beta·img2+\gamma$。这里γ的取值为0.</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> cv2</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">img1=cv2.imread(<span class="string">&#x27;test0.jpg&#x27;</span>)</span><br><span class="line">img2=cv2.imread(<span class="string">&#x27;test1.png&#x27;</span>)</span><br><span class="line">dst = cv2.addWeighted(img1,<span class="number">0.7</span>,img2,<span class="number">0.3</span>,<span class="number">0</span>)</span><br><span class="line">cv2.imshow(<span class="string">&#x27;dst&#x27;</span>,dst)</span><br><span class="line">cv2.waitKey(<span class="number">0</span>)</span><br><span class="line">cv2.destroyAllWindows()</span><br></pre></td></tr></table></figure>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/1111111.png" alt=""></p>
<h3 id="2-2-几何变换"><a href="#2-2-几何变换" class="headerlink" title="2.2 几何变换"></a>2.2 几何变换</h3><p><strong>1、扩展缩放</strong>：只是改变图像的尺寸大小，cv2.resize()可以实现这个功能。在缩放时推荐cv2.INTER_AREA，在拓展时推荐cv2.INTER_CUBIC（慢）和cv2.INTER_LINEAR。默认情况下所有改变图像尺寸大小的操作使用的是<em>插值法</em>都是cv2.INTER_LINEAR。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> cv2</span><br><span class="line">img = cv2.imread(<span class="string">&#x27;test.jpg&#x27;</span>)</span><br><span class="line"><span class="comment">#下面的None本应该是输出图像的尺寸，但是因为后面我们设置了缩放因子，所以，这里为None</span></span><br><span class="line">res = cv2.resize(img,<span class="literal">None</span>,fx=<span class="number">2</span>,fy=<span class="number">2</span>,interpolation=cv2.INTER_CUBIC)</span><br><span class="line"><span class="comment">#or</span></span><br><span class="line"><span class="comment">#这里直接设置输出图像的尺寸，所以不用设置缩放因子</span></span><br><span class="line">height , width =img.shape[:<span class="number">2</span>]</span><br><span class="line">res = cv2.resize(img,(<span class="number">2</span>*width,<span class="number">2</span>*height),interpolation=cv2.INTER_CUBIC)</span><br><span class="line"><span class="keyword">while</span>(<span class="number">1</span>):</span><br><span class="line">    cv2.imshow(<span class="string">&#x27;res&#x27;</span>,res)</span><br><span class="line">    cv2.imshow(<span class="string">&#x27;img&#x27;</span>,img)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> cv2.waitKey(<span class="number">1</span>)&amp;<span class="number">0xFF</span> == <span class="number">27</span>:</span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">cv2.destroyAllWindows()</span><br></pre></td></tr></table></figure>
<p><strong>2、平移</strong>：如果想要沿（x，y）方向移动，移动的距离为（t<sub>x</sub>,t<sub>y</sub>）可以以下面方式构建移动矩阵。</p>
<script type="math/tex; mode=display">
\left[ \begin{matrix} 1 & 0 & t_x\\ 0 & 1 & t_y \end{matrix} \right]</script><p>可以使用Numpy数组构建矩阵，数据类型是np.float32，然后传给函数cv2.warpAffine()，函数cv2.warpAffine() 的第三个参数的是输出图像的大小，它的格式应该是图像的（宽，高）。应该记住的是图像的宽对应的是列数，高对应的是行数。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">img1 = cv2.imread(<span class="string">&#x27;./test1.jpg&#x27;</span>,cv2.IMREAD_COLOR) </span><br><span class="line">tx = <span class="number">20</span></span><br><span class="line">ty = <span class="number">20</span> </span><br><span class="line">affine_arr = np.float32([[<span class="number">1</span>,<span class="number">0</span>,tx],[<span class="number">0</span>,<span class="number">1</span>,ty]]) </span><br><span class="line">res = cv2.warpAffine(img1,affine_arr,(img1.shape[<span class="number">0</span>],img1.shape[<span class="number">1</span>])) </span><br><span class="line">cv2.imshow(<span class="string">&#x27;img&#x27;</span>,img1)</span><br><span class="line">cv2.imshow(<span class="string">&#x27;res&#x27;</span>,res) </span><br><span class="line">cv2.waitKey(<span class="number">0</span>)</span><br><span class="line">cv2.destroyAllWindows()</span><br></pre></td></tr></table></figure>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/image-20210430123037189.png" alt=""></p>
<p><strong>3、旋转</strong>：对一个图像旋转角度θ，需要使用下面的旋转矩阵。</p>
<script type="math/tex; mode=display">
\left[ \begin{matrix} cos\theta & -sin\theta\\ sin\theta & cos\theta \end{matrix} \right]</script><p>但OpenCVC允许在任意地方进行旋转，所以矩阵应该为:</p>
<script type="math/tex; mode=display">
\left[ \begin{matrix} \alpha & \beta & (1-\alpha)·center_x-\beta·center_y\\ -\beta & \alpha & \beta·center_x+(1-\alpha)·center_y\end{matrix} \right]</script><p>其中α = scale · cos θ，为构建旋转矩阵，OpenCV提供了一个函数cv2.getRotationMatrix2D。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">img=cv2.imread(<span class="string">&#x27;test1.jpg&#x27;</span>,<span class="number">0</span>)</span><br><span class="line">rows,cols=img.shape</span><br><span class="line"><span class="comment"># 这里的第一个参数为旋转中心，第二个为旋转角度，第三个为旋转后的缩放因子</span></span><br><span class="line"><span class="comment"># 可以通过设置旋转中心，缩放因子，以及窗口大小来防止旋转后超出边界的问题</span></span><br><span class="line">m=cv2.getRotationMatrix2D((cols/<span class="number">2</span>,rows/<span class="number">2</span>),<span class="number">45</span>,<span class="number">0.6</span>)</span><br><span class="line">dst=cv2.warpAffine(img,m,(<span class="number">2</span>*cols,<span class="number">2</span>*rows))</span><br><span class="line">cv2.imshow(<span class="string">&#x27;img&#x27;</span>,img)</span><br><span class="line">cv2.imshow(<span class="string">&#x27;dst&#x27;</span>,dst)</span><br><span class="line">cv2.waitKey(<span class="number">0</span>)</span><br><span class="line">cv2.destroyAllWindows()</span><br></pre></td></tr></table></figure>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/22222.png" alt="22222"></p>
<p><strong>4、仿射变换</strong>：在仿射变换中，原图中所有平行线在结果图像中同样平行。为创建这个矩阵，需要从原图像中找到三个点以及他们在输出图像中的位置，然后cv2.getAffineTransForm()会创建一个2X3的矩阵。最后这个矩阵会被传给函数cv2.warpAffine()</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> cv2</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line">img = cv2.imread(<span class="string">&#x27;test1.jpg&#x27;</span>)</span><br><span class="line">rows, cols, ch = img.shape</span><br><span class="line"> </span><br><span class="line">pts1 = np.float32([[<span class="number">0</span>, <span class="number">0</span>], [cols - <span class="number">1</span>, <span class="number">0</span>], [<span class="number">0</span>, rows - <span class="number">1</span>]])</span><br><span class="line">pts2 = np.float32([[cols * <span class="number">0.2</span>, rows * <span class="number">0.1</span>], [cols * <span class="number">0.9</span>, rows * <span class="number">0.2</span>], [cols * <span class="number">0.1</span>, rows * <span class="number">0.9</span>]])</span><br><span class="line"> </span><br><span class="line">M = cv2.getAffineTransform(pts1, pts2)</span><br><span class="line">dst = cv2.warpAffine(img, M, (cols, rows))</span><br><span class="line"> </span><br><span class="line">cv2.imshow(<span class="string">&#x27;image&#x27;</span>, dst)</span><br><span class="line">k = cv2.waitKey(<span class="number">0</span>)</span><br><span class="line"><span class="keyword">if</span> k == <span class="built_in">ord</span>(<span class="string">&#x27;s&#x27;</span>):</span><br><span class="line">    cv2.imwrite(<span class="string">&#x27;Rachel1.jpg&#x27;</span>, dst)</span><br><span class="line">    cv2.destroyAllWindows()</span><br></pre></td></tr></table></figure>
<p><img src="C:\Users\zhou\AppData\Roaming\Typora\typora-user-images\image-20210430130001963.png" alt=""></p>
<p><strong>5、透视变换</strong>：对于视角变换，我们需要一个3x3变换矩阵。在变换前后直线还是直线。需要在原图上找到4个点，以及他们在输出图上对应的位置，这四个点中任意三个都不能共线，可以有函数cv2.getPerspectiveTransform()构建，然后这个矩阵传给函数cv2.warpPerspective()</p>
<p><img src="C:\Users\zhou\AppData\Roaming\Typora\typora-user-images\image-20210430130315466.png" alt="image-20210430130315466"></p>
<h3 id="2-3-ROI和泛洪填充"><a href="#2-3-ROI和泛洪填充" class="headerlink" title="2.3 ROI和泛洪填充"></a>2.3 ROI和泛洪填充</h3><p>图像ROI（region of intrest:感兴趣区域）的提取往往是图像处理中的第一步，而且也是非常关键的一步，ROI区域的提取能够在消除一些噪声的同时减少后续图像处理的数据量，是非常常用的方法。</p>
<p>  <strong>ROI有什么用？</strong></p>
<p>  ROI属于IVE技术的一种，IVE指的是Intelligent video encoding, 即智能视频编码， IVE技术可以根据客户要求对视频进行智能编码，并在不损失图像质量的前提下，优化视频编码性能，最终降低网络带宽占用率和减少存储空间。</p>
<p>在监控画面中，有些监控区域是不需要被监控或无关紧要，例如天空，墙壁， 草地等等监控对象，普通网络监控摄像机对整个区域进行视频编码（压缩）并传输，这样就给网络带宽和视频存储带来了压力。而ROI智能视频编码技术却很好的解决了这个问题，ROI功能的摄像机可以让用户选择画面中感兴趣的区域，启用ROI功能后，重要的或者移动的区域将会进行高质量无损编码， 而对那些不移动，不被选择的区域降低其码率和图像质量，进行标准清晰度视频压缩，甚至是不传输这部分区域视频，达到节省网络带宽占用和视频存储空间。  </p>
<p>例如如下图所示，通过opencv提取出图片中的荷花主体。</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/image-20210506213240571.png" alt=""></p>
<h2 id="第三章-模糊操作"><a href="#第三章-模糊操作" class="headerlink" title="第三章 模糊操作"></a>第三章 模糊操作</h2><p><strong>模糊原理：</strong>基于离散卷积，不同的卷积得到不同的卷积效果，模糊是卷积的表象。</p>
<p>如果使用二维数字图像Image作为我们的输入，就需使用二维卷积核Kernel，则：</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/clip_image002.gif" alt=""></p>
<p>卷积运算由图表示：</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/image-20210506214718559.png" alt=""></p>
<h3 id="3-1-均值模糊"><a href="#3-1-均值模糊" class="headerlink" title="3.1 均值模糊"></a>3.1 均值模糊</h3><p>均值滤波是典型的线性滤波算法，模糊是卷积的一种表象，所有的滤波模板都是使卷积框覆盖区域所有像素点与模板相乘后得到的值作为中心像素的值，比如一个3 * 3的模板其实就可以如下表示：</p>
<script type="math/tex; mode=display">
\frac{1}{9} \left[ \begin{matrix} 1 & 1 & 1\\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{matrix} \right]</script><p>opencv中提供了cv.blur () AP可以直接均值模糊，例如：经过上述5*5的卷积核模糊变换后，效果如下：</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/image-20210506220323051.png" alt=""></p>
<h3 id="3-2-中值模糊"><a href="#3-2-中值模糊" class="headerlink" title="3.2 中值模糊"></a>3.2 中值模糊</h3><p>中值模糊方法在去除脉冲噪声、斑点噪声（speckle noise）、椒盐噪声（salt-and-pepper noise）、图像扫描噪声的同时又能保留凸图像边缘细节。</p>
<p>中值滤波与均值滤波比较：</p>
<p>优势是，在均值滤波器中，由于噪声成分被放入平均计算中，所以输出受到了噪声的影响；而在中值滤波其中，噪声成分很难选上，所以几乎不会影响到输出。</p>
<p>劣势是，中值滤波花费的时间是均值滤波的5倍以上。</p>
<p>注意：中值滤波虽然可以克服线性滤波器所带来的图像细节模糊，但是在线、尖顶等细节多的图像不宜用中值滤波。</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/中值滤波.png" alt=""></p>
<h3 id="3-3-高斯模糊"><a href="#3-3-高斯模糊" class="headerlink" title="3.3 高斯模糊"></a>3.3 高斯模糊</h3><p>高斯模糊本质上是低通滤波器，输出图像的每个像素点是原图像上对应像素点与周围像素点的加权和，原理并不复杂。做久了卷积神经网络看这个分外亲切，就是用高斯分布（正态分布）权值矩阵与原始图像矩阵做卷积运算而已。</p>
<p>正态分布显然是一种可取的权重分配模式：</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/正态分布.png" alt=""></p>
<p>在图形上，正态分布是一种钟形曲线，越接近中心，取值越大，越远离中心，取值越小。计算平均值的时候，我们只需要将”中心点”作为原点，其他点按照其在正态曲线上的位置，分配权重，就可以得到一个加权平均值。</p>
<p>上面的正态分布是一维的，图像都是二维的，所以需要二维的正态分布。</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/正态分布2D.png" alt=""></p>
<p>正态分布的密度函数叫做“高斯函数”（Gaussian function）。它的一维形式是：</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/3-1.png" style="zoom:50%;" /></p>
<p>其中，μ是x的均值，σ是x的方差。因为计算平均值的时候，中心点就是原点，所以μ等于0。</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/3-2.png" style="zoom:50%;" /></p>
<p>根据一维高斯函数，可以推导得到二维高斯函数：</p>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/3-3.png" style="zoom:50%;" /></p>
<p>有了这个函数 ，就可以计算每个点的权重了。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> cv2</span><br><span class="line"></span><br><span class="line">img = cv2.imread(<span class="string">&#x27;lena.png&#x27;</span>)</span><br><span class="line">img_ = cv2.GaussianBlur(img, ksize=(<span class="number">9</span>, <span class="number">9</span>), sigmaX=<span class="number">0</span>, sigmaY=<span class="number">0</span>)</span><br><span class="line"></span><br><span class="line">cv2.imshow(<span class="string">&#x27;Source image&#x27;</span>,img)</span><br><span class="line">cv2.imshow(<span class="string">&#x27;blur image&#x27;</span>,img_)</span><br><span class="line">cv2.waitKey()</span><br></pre></td></tr></table></figure>
<p><img src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/image-20210507094629011.png" alt=""></p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="https://gitee.com/zwyywz/zwyywz.git">Zhouwy</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://gitee.com/zwyywz/zwyywz.git/2020/04/26/DigitalImageProcessing/">https://gitee.com/zwyywz/zwyywz.git/2020/04/26/DigitalImageProcessing/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://gitee.com/zwyywz/zwyywz.git" target="_blank">啊粥啊周舟の部落阁</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/zwyywz/tags/Python/">Python</a><a class="post-meta__tags" href="/zwyywz/tags/OpenCV/">OpenCV</a></div><div class="post_share"><div class="social-share" data-image="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/DIP.png" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="/zwyywz/img/wechat.jpg" target="_blank"><img class="post-qr-code-img" src="/zwyywz/img/wechat.jpg" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="/zwyywz/img/alipay.jpg" target="_blank"><img class="post-qr-code-img" src="/zwyywz/img/alipay.jpg" alt="支付宝"/></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/zwyywz/2020/09/20/Mac%20M1%20Pro%20%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/" title="Mac M1 Pro 深度学习环境搭建"><img class="cover" src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/apple-macbook-pro-m1-2020-5-20230410110609763.jpg" onerror="onerror=null;src='/zwyywz/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">Mac M1 Pro 深度学习环境搭建</div></div></a></div><div class="next-post pull-right"><a href="/zwyywz/2020/04/01/DeepLearningAndTensorFlow/" title="深度学习与TensorFlow"><img class="cover" src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/deep_learning.png" onerror="onerror=null;src='/zwyywz/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">深度学习与TensorFlow</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/zwyywz/2020/04/01/DeepLearningAndTensorFlow/" title="深度学习与TensorFlow"><img class="cover" src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/deep_learning.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-04-01</div><div class="title">深度学习与TensorFlow</div></div></a></div><div><a href="/zwyywz/2022/06/15/%E5%8D%B7%E7%A7%AF%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%88%86%E7%B1%BB%E5%9B%BE%E7%89%87/" title="机器视觉的算法研究"><img class="cover" src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/t.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-06-15</div><div class="title">机器视觉的算法研究</div></div></a></div><div><a href="/zwyywz/2022/06/15/%E5%9F%BA%E4%BA%8EOpenCV%E5%92%8CC++%E8%BD%A6%E9%81%93%E7%BA%BF%E6%A3%80%E6%B5%8B/" title="基于OpenCV和C++车道线检测"><img class="cover" src="https://blog-1300216920.cos.ap-nanjing.myqcloud.com/weixin15937410430092-20230410105251467.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-06-15</div><div class="title">基于OpenCV和C++车道线检测</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%95%B0%E5%AD%97%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%EF%BC%88%E5%9F%BA%E4%BA%8EPython-Opencv%EF%BC%89"><span class="toc-number">1.</span> <span class="toc-text">数字图像处理（基于Python-Opencv）</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%9B%BE%E5%83%8F%E5%9F%BA%E7%A1%80"><span class="toc-number">1.1.</span> <span class="toc-text">第一章 图像基础</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-1-%E5%9B%BE%E5%83%8F%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5"><span class="toc-number">1.1.1.</span> <span class="toc-text">1.1 图像的基本概念</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-2-%E5%9B%BE%E5%83%8F%E7%9A%84%E5%AD%98%E5%82%A8%E6%A0%BC%E5%BC%8F"><span class="toc-number">1.1.2.</span> <span class="toc-text">1.2 图像的存储格式</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C"><span class="toc-number">1.2.</span> <span class="toc-text">第二章 基础操作</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#2-1-%E5%9B%BE%E5%83%8F%E7%9A%84%E7%AE%97%E6%95%B0%E8%BF%90%E7%AE%97"><span class="toc-number">1.2.1.</span> <span class="toc-text">2.1 图像的算数运算</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2-%E5%87%A0%E4%BD%95%E5%8F%98%E6%8D%A2"><span class="toc-number">1.2.2.</span> <span class="toc-text">2.2 几何变换</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-3-ROI%E5%92%8C%E6%B3%9B%E6%B4%AA%E5%A1%AB%E5%85%85"><span class="toc-number">1.2.3.</span> <span class="toc-text">2.3 ROI和泛洪填充</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%A8%A1%E7%B3%8A%E6%93%8D%E4%BD%9C"><span class="toc-number">1.3.</span> <span class="toc-text">第三章 模糊操作</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#3-1-%E5%9D%87%E5%80%BC%E6%A8%A1%E7%B3%8A"><span class="toc-number">1.3.1.</span> <span class="toc-text">3.1 均值模糊</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-2-%E4%B8%AD%E5%80%BC%E6%A8%A1%E7%B3%8A"><span class="toc-number">1.3.2.</span> <span class="toc-text">3.2 中值模糊</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-3-%E9%AB%98%E6%96%AF%E6%A8%A1%E7%B3%8A"><span class="toc-number">1.3.3.</span> <span class="toc-text">3.3 高斯模糊</span></a></li></ol></li></ol></li></ol></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2023 By Zhouwy</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">简</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/zwyywz/js/utils.js"></script><script src="/zwyywz/js/main.js"></script><script src="/zwyywz/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.min.js"></script><div class="js-pjax"><script>if (!window.MathJax) {
  window.MathJax = {
    tex: {
      inlineMath: [ ['$','$'], ["\\(","\\)"]],
      tags: 'ams'
    },
    chtml: {
      scale: 1.1
    },
    options: {
      renderActions: {
        findScript: [10, doc => {
          for (const node of document.querySelectorAll('script[type^="math/tex"]')) {
            const display = !!node.type.match(/; *mode=display/)
            const math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display)
            const text = document.createTextNode('')
            node.parentNode.replaceChild(text, node)
            math.start = {node: text, delim: '', n: 0}
            math.end = {node: text, delim: '', n: 0}
            doc.math.push(math)
          }
        }, ''],
        insertScript: [200, () => {
          document.querySelectorAll('mjx-container').forEach(node => {
            if (node.hasAttribute('display')) {
              btf.wrap(node, 'div', { class: 'mathjax-overflow' })
            } else {
              btf.wrap(node, 'span', { class: 'mathjax-overflow' })
            }
          });
        }, '', false]
      }
    }
  }
  
  const script = document.createElement('script')
  script.src = 'https://cdn.jsdelivr.net/npm/mathjax/es5/tex-mml-chtml.min.js'
  script.id = 'MathJax-script'
  script.async = true
  document.head.appendChild(script)
} else {
  MathJax.startup.document.state(0)
  MathJax.texReset()
  MathJax.typesetPromise()
}</script></div><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>